package com.zhuoyue.web.controller.system;


import com.zhuoyue.common.annotation.LogTakep;
import com.zhuoyue.common.constant.ExtrasCode;
import com.zhuoyue.common.core.controller.ControllerResult;
import com.zhuoyue.common.core.domain.AjaxResult;
import com.zhuoyue.common.core.domain.AppUserDO;
import com.zhuoyue.common.core.domain.entity.SysDept;
import com.zhuoyue.common.core.domain.entity.SysThirdData;
import com.zhuoyue.common.enums.ResultCode;
import com.zhuoyue.common.utils.StringUtils;
import com.zhuoyue.system.domain.TblMessage;
import com.zhuoyue.system.domain.po.*;
import com.zhuoyue.system.domain.vo.TblAppUserVo;
import com.zhuoyue.system.mapper.TblMessageMapper;
import com.zhuoyue.system.service.ISysDeptService;
import com.zhuoyue.system.service.ISysThirdDataService;
import com.zhuoyue.system.service.ITblAppUserService;
import com.zhuoyue.system.service.JPushService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.http.HttpHeaders;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.*;
import java.util.stream.Collectors;

/**
 * ClassName: JpushController <br/>
 * Description: <br/>
 * date: 2019/2/20 12:24<br/>
 *
 * @author wjming<br />
 * @version 1.0
 */
@Api(value = "推送", tags = "向用户推送消息")
@Controller
@RequestMapping("/zhuoyue/jpush")
public class JpushController {

    @Autowired
    private JPushService jPushService;

    @Autowired
    private ISysThirdDataService thirdDataService;

    @Autowired
    private ITblAppUserService tblAppUserService;

    @Autowired
    private ISysDeptService deptService;

    @Autowired
    private TblMessageMapper messageMapper;

    @Value("${jiguang.envir_prod}")
    private boolean environmentProd;

    /**
     * 1.给单个用户推送消息
     */
    @GetMapping("/jpushToOneUser")
    @ResponseBody
    @LogTakep(takeMessage = "user", operationEvent = "111")
    @ApiOperation(value = "单用户推送", notes = "给单用户推送消息")
    public AjaxResult jpushToOneUser(
            @RequestParam(value = "id", required = false) String id
            , @RequestParam(value = "sourceId", required = false) String sourceId
            , @RequestParam(value = "title", required = false) String title
            , @RequestParam(value = "pushMessage", required = false) String pushMessage
            , @RequestParam(value = "pushType", required = false) String pushType
            , @RequestParam(value = "sourceType", required = false) String sourceType
            , @RequestParam(value = "messageCode", required = false) String messageCode
            , @RequestParam(value = "orgCode", required = false) String orgCode
    ) {

        ControllerResult controllerResultObj = new ControllerResult();

        if (sourceId == null || "".equals(sourceId)) {
            return AjaxResult.error("用户未登录，无法发送推送");
        }

        try {
            SysDept sysDept = deptService.selectDeptByOrgCode(orgCode);
            if (sysDept == null) {
                return AjaxResult.error("该组织没有添加极光推送");
            }
            SysThirdData sysThirdData = thirdDataService.selectJPushData(sysDept.getDeptId());
            if (sysThirdData == null) {
                return AjaxResult.error("该组织没有添加极光推送");
            }

//            jPushService.send(title, pushMessage, "8", sourceId, ExtrasCode.SYSTEM_PUSH, "", id, sourceType, sysThirdData);

            // 转发push的请求体json内容
            PushBody pushBody = new PushBody();
            if ("1".equals(sourceType)) {
                pushBody.setPlatform("ios");
            } else if ("2".equals(sourceType)) {
                pushBody.setPlatform("android");
            } else {
                pushBody.setPlatform("all");
            }
            Map<String, String> extras = new HashMap<>(1);
            extras.put("type", ExtrasCode.SYSTEM_PUSH);

            // 填充安卓内容
            PushAndroid android = new PushAndroid();
            android.setTitle(title);
            android.setAlert(pushMessage);
            android.setExtras(extras);
            // 填充ios内容
            PushIos ios = new PushIos();
            Map<String, String> iosAlert = new HashMap<>(2);
            iosAlert.put("title", title);
            iosAlert.put("body", pushMessage);
            ios.setAlert(iosAlert);
            ios.setExtras(extras);
            // 填充options
            PushOptions options = new PushOptions();
            options.setTime_to_live(846000);
            options.setApns_production(apnsProduction);
            // 对象赋值
            PushNotification notification = new PushNotification();
            notification.setAlert(title);
            notification.setAndroid(android);
            notification.setIos(ios);
            pushBody.setNotification(notification);
            pushBody.setOptions(options);
            pushBody.getNotification().getAndroid().setUri_activity(sysThirdData.getUriActivity());
            pushBody.getNotification().getAndroid().setUri_action(sysThirdData.getUriAction());
            Map<String, List<String>> audienceMap = new HashMap<>(1);
            List<String> audience = new ArrayList<>();
            audience.add(sourceId);
            audienceMap.put("registration_id", audience);
            pushBody.setAudience(audienceMap);

            // 设置请求头
            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.setContentType(MediaType.APPLICATION_JSON);
            String authStr = sysThirdData.getDataKey() + ":" + sysThirdData.getSecret();
            httpHeaders.set("Authorization", "Basic " + Base64.getEncoder().encodeToString(authStr.getBytes()));
            System.out.println(com.alibaba.fastjson.JSONObject.toJSONString(pushBody));
            HttpEntity<PushBody> httpEntity = new HttpEntity<>(pushBody, httpHeaders);
            RestTemplate restTemplate = new RestTemplate();
            List<TblMessage> messageList = new ArrayList<>(1);
            TblMessage message = new TblMessage();
            message.setTitle(title);
            message.setContent(pushMessage);
            message.setUserId(id);
            message.setHasRead("0");
            message.setSender(sourceId);
            message.setSendType("2");
            message.setMessageType("8");
            messageList.add(message);
            messageMapper.insertSystemPushMessage(messageList);
            ResponseEntity<PushResult> responseEntity = restTemplate.postForEntity(pushUrl, httpEntity, PushResult.class);

            return new AjaxResult(200, "推送成功", null);


        } catch (Exception e) {
            controllerResultObj.setMsg("数据请求接口异常");
            controllerResultObj.setCode(ResultCode.FAIL);
        }
        return new AjaxResult(200, "推送成功", null);

    }


    /**
     * 2.给所有用户推送消息
     */
    @RequestMapping("/jpushToAllUser")
    @ResponseBody
    public AjaxResult jpushToAllUser(HttpServletRequest request,
                                     HttpServletResponse response, HttpSession session) {

        // ControllerResult controllerResultObj = new ControllerResult();
        //String token = request.getParameter("token");
        String title = request.getParameter("title");//获取主题
        String pushMessage = request.getParameter("pushMessage");//获取推送的内容
        String pustType = request.getParameter("pustType");//获取推送的类型
        //String sourceType = request.getParameter("sourceType");//获取手机类型

        try {
            // System.out.println("进入接口: " + "  " + title + "  " + pushMessage + "  " + pustType + "  " + sourceType);
            jPushService.sendAll(title, pushMessage, "8", "", "", "zyzn");
            //jPushService.send( title, pushMessage, "8", sourceId, "", "", id, sourceType, "zyzn");
            //System.out.println("全用户推送成功");
            //controllerResultObj.setSuccess(true);
            // controllerResultObj.setCode(ResultCode.SUCCESS);
            return new AjaxResult(200, "推送成功", null);

        } catch (Exception e) {
            // controllerResultObj.setMsg("数据请求接口异常");
            //controllerResultObj.setCode(ResultCode.FAIL);
            return new AjaxResult(0, "推送失败", null);
        }

        //return new AjaxResult(0, "推送失败", null);
    }


    /**
     * 3.给选中用户推送消息
     */
    @RequestMapping("/jpushToCheckUser.do")
    @ResponseBody
    public ControllerResult jpushToCheckUser(HttpServletRequest request,
                                             HttpServletResponse response, HttpSession session) {

        ControllerResult controllerResultObj = new ControllerResult();
        String token = request.getParameter("token");
        String checkedUser = request.getParameter("checkedUser");
        //获取主题
        String title = request.getParameter("title");
        //获取推送的内容
        String pushMessage = request.getParameter("pushMessage");
        //获取推送的类型
        String pustType = request.getParameter("pustType");
        //消息操作的类型
        String messageCode = request.getParameter("messageCode");

        try {
            System.out.println("进入接口: " + checkedUser);


            JSONArray array = JSONArray.fromObject(checkedUser);
            List<?> deviceReturns = JSONArray.toList(array, new AppUserDO(), new JsonConfig());

            for (int i = 0; i < deviceReturns.size(); i++) {
                JSONObject ob = JSONObject.fromObject(deviceReturns.get(i));
                Map<String, Object> checkedUserMap = (Map<String, Object>) ob;
                String sourceId = checkedUserMap.get("sourceId").toString();
                System.out.println("sourceId:  " + sourceId);
                String sourceType = checkedUserMap.get("sourceType").toString();

                System.out.println("sourceType:  " + sourceType);
                String id = checkedUserMap.get("id").toString();
                System.out.println("id" + id);
               /* jPushService.send(title,
                        pushMessage, messageCode,
                        sourceId, pustType, "", id
                                + "", sourceType);*/
            }


            controllerResultObj.setSuccess(true);
            controllerResultObj.setCode(ResultCode.SUCCESS);
            return controllerResultObj;

        } catch (Exception e) {
            controllerResultObj.setMsg("数据请求接口异常");
            controllerResultObj.setCode(ResultCode.FAIL);
        }

        return controllerResultObj;
    }

    @Value("${jiguang.apns_production}")
    private boolean apnsProduction;

    @Value("${jiguang.pushUrl}")
    private String pushUrl;

    @GetMapping("/jpushToSomeUser")
    @ResponseBody
    public AjaxResult jpushToSomeUser(String title, String content, Long deptId, String position, String gender, String sourceType) {
        // 获取secret, key
        List<SysThirdData> sysThirdDataList = new ArrayList<>();
        // 若是顶层组织, 则推送其下所有组织中的用户
        if (deptId == 100) {
            sysThirdDataList = thirdDataService.selectJPushDataList();
        } else {
            // 获取单个组织secret, key
            SysThirdData sysThirdData = thirdDataService.selectJPushData(deptId);
            if (sysThirdData == null) {
                return AjaxResult.error("该组织没有添加极光推送");
            }
            sysThirdDataList.add(sysThirdData);
        }

        // 获取组织编码
        SysDept sysDept;
        // 需要推送的用户
        TblAppUserPo appUserPo = new TblAppUserPo();
        appUserPo.setPosition(position);
        if ((!"1".equals(sourceType) && !"2".equals(sourceType) && !"all".equals(sourceType))) {
            appUserPo.setSourceType(null);
        } else {
            appUserPo.setSourceType(sourceType);
        }
        if (!"0".equals(gender) && !"1".equals(gender) && !"2".equals(gender) && !"all".equals(gender)) {
            appUserPo.setGender(null);
        } else {
            appUserPo.setGender(gender);
        }


        List<TblAppUserVo> tblAppUserVos;
        int pushSuccessCount = 0;
        // 转发push的请求体json内容
        PushBody pushBody = new PushBody();
        if ("1".equals(sourceType)) {
            pushBody.setPlatform("ios");
        } else if ("2".equals(sourceType)) {
            pushBody.setPlatform("android");
        } else {
            pushBody.setPlatform("all");
        }
        Map<String, String> extras = new HashMap<>(1);
        extras.put("type", ExtrasCode.SYSTEM_PUSH);

        // 填充安卓内容
        PushAndroid android = new PushAndroid();
        android.setTitle(title);
        android.setAlert(content);
        android.setExtras(extras);
        // 填充ios内容
        PushIos ios = new PushIos();
        Map<String, String> iosAlert = new HashMap<>(2);
        iosAlert.put("title", title);
        iosAlert.put("body", content);
        ios.setAlert(iosAlert);
        ios.setExtras(extras);
        // 填充options
        PushOptions options = new PushOptions();
        options.setTime_to_live(846000);
        options.setApns_production(apnsProduction);
        // 对象赋值
        PushNotification notification = new PushNotification();
        notification.setAlert(title);
        notification.setAndroid(android);
        notification.setIos(ios);
        pushBody.setNotification(notification);
        pushBody.setOptions(options);

        // 循环推送每个组织的用户
        for (SysThirdData sysThirdData : sysThirdDataList) {
            // 添加安卓推送的信息
            pushBody.getNotification().getAndroid().setUri_activity(sysThirdData.getUriActivity());
            pushBody.getNotification().getAndroid().setUri_action(sysThirdData.getUriAction());
            // 查询组织编码并查询推送用户
            sysDept = deptService.selectDeptById(sysThirdData.getDeptId());
            appUserPo.setSelectedOrgCode(sysDept.getOrgCode());
            tblAppUserVos = tblAppUserService.selectTblAppUserPushList(appUserPo);

            // 测试, 只推送手机号17605799197和15707061018且是rjbcs组织的用户
//            tblAppUserVos = tblAppUserVos.stream().filter(item -> "rjbcs".equals(item.getOrganizationCode()) && ("17605799197".equals(item.getAccount()) || "15707061018".equals(item.getAccount()))).collect(Collectors.toList());
            // 测试, 只推送手机号17605799197的用户
//            tblAppUserVos = tblAppUserVos.stream().filter(item -> "17605799197".equals(item.getAccount())).collect(Collectors.toList());

            // 仅有用户才推送
            if (tblAppUserVos.size() > 0) {
                List<List<TblAppUserVo>> splitList = StringUtils.splitList(tblAppUserVos, 1000);
                for (List<TblAppUserVo> appUserVos : splitList) {
                    // 获取用户的sourceId列表
                    List<String> audience = appUserVos.stream().map(TblAppUserVo::getSourceId).collect(Collectors.toList());
                    pushSuccessCount += audience.size();
                    Map<String, List<String>> audienceMap = new HashMap<>(1);
                    audienceMap.put("registration_id", audience);
                    pushBody.setAudience(audienceMap);

                    // 设置请求头
                    HttpHeaders httpHeaders = new HttpHeaders();
                    httpHeaders.setContentType(MediaType.APPLICATION_JSON);
                    String authStr = sysThirdData.getDataKey() + ":" + sysThirdData.getSecret();
                    httpHeaders.set("Authorization", "Basic " + Base64.getEncoder().encodeToString(authStr.getBytes()));
                    HttpEntity<PushBody> httpEntity = new HttpEntity<>(pushBody, httpHeaders);

                    RestTemplate restTemplate = new RestTemplate();
                    try {
                        List<TblMessage> messageList = new ArrayList<>(appUserVos.size());
                        for (TblAppUserVo tblAppUserVo : appUserVos) {
                            TblMessage message = new TblMessage();
                            message.setTitle(title);
                            message.setContent(content);
                            message.setUserId(tblAppUserVo.getId());
                            message.setHasRead("0");
                            message.setSender(tblAppUserVo.getSourceId());
                            message.setSendType("2");
                            message.setMessageType("8");
                            messageList.add(message);
                        }

                        if (environmentProd) {
                            //推送消息
                            ResponseEntity<PushResult> responseEntity = restTemplate.postForEntity(pushUrl, httpEntity, PushResult.class);
                            //添加推送记录
                            messageMapper.insertSystemPushMessage(messageList);
                            System.out.println(responseEntity.getBody());
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        System.out.println("共推送" + pushSuccessCount + "人");
        return AjaxResult.success(pushSuccessCount);
    }
}
